let isDragging = false;
let step = -1;
let canvasHistory = []
class CanvasTools {
    constructor(canvas,ctx,oriCtx) {
        // 画笔宽度 6-56
        this.oriCtx = oriCtx
        this.brushWidth = 20
        this.brushColor = '#000'
        this.slidePercent = (this.brushWidth -6) / 56
        this.canvas = canvas;
        this.ctx = ctx;
        this.canvasWidth = canvas.offsetWidth
        this.canvasHeight = canvas.offsetHeight
        this.offsetRight = 40
        this.bindEvent()
        this.isMask = false;
        // slider
        this.targetObj = [{
            key:'sliderAttr',
            clickCb:'slideClick',
            startCb:'slideStart',
            moveCb:'slideMove',
            endCb:'slideEnd',
        },{
            key:'imageAttr',
            clickCb:'imageClick',
            startCb:'imageStart',
            moveCb:'imageMove',
            endCb:'imageEnd',
        }]
        this.sliderAttr =  {
            x:this.canvasWidth - this.offsetRight,
            y:this.offsetRight,
            width:4,
            height:100,
            gap:20,
            isDragging:false,
            circleY:40 + this.offsetRight
        }
        this.imageAttr = {
            x:0,
            y:0,
            width:0,
            height:0,
            gap:0,
            isDragging:false,
            isContinue:true
        }
        this.draw()
    }
    draw(){
        console.log(this.slidePercent)
        this.drawSliderTrack({offsetY:this.sliderAttr.height *  (1 - this.slidePercent) + 40})
        this.drawCircle(this.sliderAttr.height *  (1 - this.slidePercent) + 40)
        this.drawSlider()
    }
    bindEvent(){
        this.canvas.addEventListener('mousedown', this.startDragging.bind(this), false);
        this.canvas.addEventListener('mousemove', this.dragSlider.bind(this), false);
        this.canvas.addEventListener('mouseup', this.stopDragging.bind(this), false);
        this.canvas.addEventListener('click', this.handleClick.bind(this), false);
    }
    startDragging(e){
        for(let i = 0; i < this.targetObj.length;i++) {
            if(this.targetIsClick(e,this[this.targetObj[i].key])) {
                this[this.targetObj[i].startCb](e)
            }
        }
    }
    dragSlider(e){
        for(let i = 0; i < this.targetObj.length;i++) {
            if(this.targetIsClick(e,this[this.targetObj[i].key])) {
                this[this.targetObj[i].moveCb](e)
            } else if(!this[this.targetObj[i].key].isContinue){
                this[this.targetObj[i].key].isDragging = false
            }
        }
    }
    stopDragging(e){
        for(let i = 0; i < this.targetObj.length;i++) {
            if(this.targetIsClick(e,this[this.targetObj[i].key])) {
                this[this.targetObj[i].endCb](e)
            }
        }
    }
    // canvas点击
    handleClick(e){
        for(let i = 0; i < this.targetObj.length;i++) {
            if(this.targetIsClick(e,this[this.targetObj[i].key])) {
                this[this.targetObj[i].clickCb](e)
            }
        }
    }
    // 目标元素点击了
    targetIsClick(e,val) {
        const offsetX = e.offsetX;
        const offsetY = e.offsetY;
        return (val.x - val.gap < offsetX && offsetX< (val.x + val.width) + val.gap) && (val.y< offsetY && offsetY< (val.y + val.height));
    }
    slideStart(e){
        this.sliderAttr.isDragging = true;
    }
    slideMove(e){
        if (!this.sliderAttr.isDragging) return;
        let val = this[this.targetObj[0].key]
        if((val.y < e.offsetY && e.offsetY< (val.y + val.height))) {
            this.brushWidth = (1 - (e.offsetY - 40) / this.sliderAttr.height) * 56
            this.slideClick(e)
        }
        
    }
    slideEnd(e){
        if (!this.sliderAttr.isDragging) return;
        this.sliderAttr.isDragging = false;
        step++;
        if (step < canvasHistory.length) {
            canvasHistory.length = step; // 截断数组
        }
        canvasHistory.push(this.canvas.toDataURL());
    }
    // 目标元素点击
    slideClick(e){
        this.ctx.clearRect(this.sliderAttr.x - this.sliderAttr.gap,this.sliderAttr.y - this.sliderAttr.gap,this.sliderAttr.gap * 2,this.sliderAttr.height + this.sliderAttr.gap * 2)
        this.drawSliderTrack(e)
        this.drawCircle(e.offsetY)
        this.drawSlider()
    }
    drawSlider(){
        
    }
    // 圆
    drawCircle(y) {
        this.ctx.beginPath();
        this.ctx.fillStyle = '#2196f3';
        this.ctx.strokeStyle = '#2196f3';
        this.ctx.globalAlpha = 0.1
        this.ctx.arc(this.sliderAttr.x + this.sliderAttr.width/2,y,16,0,2*Math.PI);
        this.ctx.stroke()
        this.ctx.fill()

        this.ctx.beginPath();
        this.ctx.fillStyle = '#2196f3';
        this.ctx.strokeStyle = '#2196f3';
        this.ctx.globalAlpha = 1
        this.ctx.arc(this.sliderAttr.x + this.sliderAttr.width/2,y,8,0,2*Math.PI);
        this.ctx.stroke()
        this.ctx.fill()
        this.ctx.closePath()
    }
    // 圆角矩形轨道
    drawSliderTrack(e){
        // 轨道
        this.ctx.beginPath();
        this.ctx.fillStyle = '#c6e2f8';
        this.ctx.strokeStyle = '#c6e2f8';
        this.ctx.roundRect(this.sliderAttr.x, this.sliderAttr.y, this.sliderAttr.width, this.sliderAttr.height, this.sliderAttr.width / 2);
        this.ctx.stroke();
        this.ctx.fill();
        this.ctx.closePath();
        
        this.ctx.beginPath();
        this.ctx.fillStyle = '#2196f3';
        this.ctx.strokeStyle = '#2196f3';
        this.ctx.roundRect(this.sliderAttr.x, e.offsetY, this.sliderAttr.width, this.sliderAttr.height + 40 - e.offsetY, this.sliderAttr.width / 2);
        this.ctx.stroke();
        this.ctx.fill();
        this.ctx.closePath();
    }
    // 撤销方法
    canvasUndo() {
        if (step > 0) {
            step--;
            let canvasPic = new Image();
            canvasPic.src = canvasHistory[step];
            canvasPic.addEventListener('load', () => {
                this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                var dpr = window.devicePixelRatio || window.webkitDevicePixelRatio || window.mozDevicePixelRatio || 1
                this.canvas.width=canvasPic.width*dpr
                this.canvas.height=canvasPic.height*dpr
                this.ctx.scale(dpr,dpr) 
                this.ctx.drawImage(canvasPic, 0, 0);
            });
        } else {
            console.log('不能再继续撤销了');
        }
    }
    // 反撤销方法
    canvasRedo() {
        if (step < canvasHistory.length - 1) {
            step++;
            let canvasPic = new Image();
            canvasPic.src = canvasHistory[step];
            canvasPic.addEventListener('load', () => {
                this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                this.ctx.drawImage(canvasPic, 0, 0);
            });
        } else {
            console.log('已经是最新的记录了');
        }
    }
    // 图片
    imageStart(e){
        this.imageAttr.isDragging = true;
        // this.ctx.lineCap="round";
        // this.ctx.lineJoin="round";
        // this.ctx.beginPath();
        // this.ctx.moveTo(e.offsetX,e.offsetY);
        // this.ctx.lineWidth = this.brushWidth;     
        // this.ctx.strokeStyle= this.brushColor
    }
    // 图片移动涂鸦
    imageMove(e){
        if (!this.imageAttr.isDragging) return;
        if(this.isMask) {
            var w = this.brushWidth;
            // 源canvas 和 目标canvas 宽高必须相等
            let pxs = this.oriCtx.getImageData(e.offsetX-w/2, e.offsetY-w/2, w, w);
            this.ctx.putImageData(pxs, e.offsetX-w/2, e.offsetY-w/2);
        } else {
            this.ctx.beginPath();
            this.ctx.fillStyle = this.brushColor;
            this.ctx.strokeStyle = this.brushColor;
            this.ctx.arc(e.offsetX,e.offsetY,this.brushWidth,0,2*Math.PI);
            this.ctx.stroke()
            this.ctx.fill()
        }
    }
    // 涂鸦结束 保存到历史记录
    imageEnd(e){
        if (!this.imageAttr.isDragging) return;
        this.imageAttr.isDragging = false;
        // this.ctx.closePath()
        this.setHistory()
    }
    // 图片元素点击
    imageClick(e){
        this.imageAttr.isDragging = false;
    }
    clear(){
        this.ctx.clearRect(0,0,this.canvasWidth,this.canvasHeight)
    }
    // 绘制图片
    drawImage(base64Str) {
        const that = this;
        let img = new Image()
        img.src = base64Str;
        img.setAttribute('crossorigin', 'anonymous');
        img.addEventListener('load', () => {
            const w = img.width;
            const h = img.height;
            this.ctx.globalCompositeOperation = "source-over";
            if(w>this.canvasWidth || h > this.canvasHeight) {
                const aspectRatio = w / h;
                let drawWidth = this.canvasWidth;
                let drawHeight = this.canvasHeight;
                let drawX = 0;
                let drawY = 0;
                if (aspectRatio > 1) {
                    drawHeight = this.canvasWidth / aspectRatio;
                    drawY = (this.canvasHeight - drawHeight) / 2;
                } else {
                    drawWidth = this.canvasHeight * aspectRatio;
                    drawX = (this.canvasWidth - drawWidth) / 2;
                }
                this.imageAttr.x = drawX
                this.imageAttr.y = drawY
                this.imageAttr.width = drawWidth
                this.imageAttr.height = drawHeight
                this.ctx.drawImage(img, drawX, drawY, drawWidth -80, drawHeight);
                this.oriCtx.drawImage(img,drawX,drawY,drawWidth -80, drawHeight)
            } else {
                let x = (this.canvasWidth - w) / 2
                let y = (this.canvasHeight - h) / 2
                this.imageAttr.x = x
                this.imageAttr.y = y
                this.imageAttr.width = w
                this.imageAttr.height = h
                this.ctx.drawImage(img, x, y, w -80 , h);
                this.oriCtx.drawImage(img,x,y,drawWidth -80, drawHeight)
            }
            this.ctx.globalCompositeOperation = "source-over";
            this.setHistory()
        })
    }
    // 保存绘制记录
    setHistory() {
        step++;
        if (step < canvasHistory.length) {
            canvasHistory.length = step; // 截断数组
        }
        canvasHistory.push(this.canvas.toDataURL('image/png',1));
    }
    getImageData(){
        console.log(this.imageAttr,'this.imageAttr')
        // 指定图片区域
        let imgData = this.ctx.getImageData(this.imageAttr.x,this.imageAttr.y,this.imageAttr.width-80,this.imageAttr.height)
        const tempCanvas = document.createElement('canvas');
        const tempCtx = tempCanvas.getContext('2d');
        tempCanvas.width = this.imageAttr.width -80;
        tempCanvas.height = this.imageAttr.height;
        tempCtx.putImageData(imgData, 0, 0);

        return tempCanvas.toDataURL('image/png',1)
    }
}
